<style scoped>
</style>
<template>
  <van-list ref="van_list" class="request-list-slot" :loading="loading" :finished="finished" @load="load" :finished-text="list.length?finished_text:''">
    <van-pull-refresh v-model="refresh_loading" @refresh="refresh" :disabled="!pull_refresh">
      <ListSlot :list="list" :cols="cols" :mode="mode" :group_key="group_key">
        <template v-if="$slots.group" #group="slot_data">
          <slot name="group" v-bind="slot_data"></slot>
        </template>
        <template v-if="$slots.default" #default="slot_data">
          <slot name="default" v-bind="slot_data"></slot>
        </template>
      </ListSlot>
      <van-empty v-show="list.length===0&&finished&&!hidden_empty" description="暂无记录" />
    </van-pull-refresh>
  </van-list>
</template>

<script>
import {debounce, param_encode} from "@/js/s94_tool.js";
import {ajax} from "@/js/api_tool.js";
import ListSlot from "@/components/slot/ListSlot.vue";

/**请求列表
 * @prop {*}
 */
export default {
  _title_: '请求列表',
  _tip_: '请求接口，以响应的data.list数据作列表数据循环渲染子组件，每一项作为子组件的$info，滚动加载下一页',
  _css_var_:{
    ...ListSlot._css_var_,
  },
  _head_img_: '',
  _group_: '容器组件',
  components: {ListSlot},
  props:{
    url: {
      type: String,
      _label_: '列表接口',
      _tip_: '列表数据的获取接口地址',
      _required_: true,
    },
    cols: {
      type: [String, Number],
      _label_: '分栏数量',
      _tip_: '项目列表的分栏数量，1-5，默认为：1',
    },
    mode: {
      type: String,
      _label_: '列表模式',
      _tip_: 'round、round_list、round_row、其他。分别表示整体圆角、列表圆角、每一项圆角、无圆角',
    },
    group_key: {
      type: String,
      _label_: '分组键值',
      _tip_: '用于分组的键值，遇到对应值不同的项目会多生成一个group插槽内容',
    },

    data: [Object,String],
    pull_refresh: {
      type: Boolean,
      _label_: '下拉刷新',
      _tip_: '列表是否启用下拉刷新',
      _default_: "1",
    },
    finished_text: {
      type: String,
      _label_: '终止文本',
      _tip_: '列表全部加载完成后(列表为空除外)显示的文本',
      _default_: "到底了...",
    },
    hidden_empty: {
      type: Boolean,
      _label_: '隐藏空状态',
      _tip_: '',
    },

    //回到方法
    list_handle: Function,
    load_before: Function,
    refresh_before: Function,
  },
  data(){
    return {
      list: [],
      refresh_loading: false,
      loading: false,
      finished: false,

      page: {p:0, n:20},
    }
  },
  methods:{
    load: debounce(async function(){
      if (this.load_before && this.load_before()===false) return ;
      if (!this.url) return console.error('请求地址不存在');
      if (this.loading || this.finished) return;
      this.loading = true;

      let url = this.url;
      let page = Object.assign({}, this.page);
      let paramArr = [param_encode(page)];
      let dataStr = param_encode(this.data);
      if (dataStr) paramArr.push(dataStr);
      url += (~url.indexOf('?') ? '&' : '?') + paramArr.join('&');

      let list = []
      try {
        let res = await ajax(url);
        if (this.page.p !== page.p) return false; //页码不匹配，直接返回，舍弃本次响应数据
        list = res?.data?.list || [];
        this.page.p++;
      } catch (e) {
      }
      // 合并数据列表
      if (page.p <= 0) this.list = [];
      if (typeof this.list_handle === 'function') list = this.list_handle(list);
      this.list = this.list.concat(list);
      // 状态调整，由于列表渲染需要时间，避免在列表渲染前再次距离判定触发，所以 loading 修改需要延时
      this.finished = list.length < page.n;
      setTimeout(()=>{
        this.loading=false;this.refresh_loading=false;
      },50)
    }, 100),
    load_init(){
      this.list = [];
      this.page.p = 0;
      this.loading=false;
      this.finished = false;
      this.load();
    },
    refresh(){
      if (this.refresh_before && this.refresh_before()===false) {
        this.refresh_loading=false;
        return;
      }
      this.refresh_loading=false;
      this.load_init();
    },

  },
  watch: {
    url(){
      this.load_init();
    },
    data(v, oldV){
      this.load_init();
    }
  },
  computed:{},
  mounted(){
    this.loadTh = setInterval(()=>{
      this.$refs.van_list.check();
    },1000)
  },
  unmounted() {
    if (this.loadTh) clearInterval(this.loadTh);
  }
}
</script>